﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Jage.Common;
using Jage.Logic.Resources;
using Jage.Win32;

namespace Jage.GameEditor.Controls.Resources
{
    public partial class ResourceBrowser : Form
    {

        public ResourceBrowser()
        {
            InitializeComponent();
            AllowedResourceTypes = new List<ResourceType>();
        }

        private void ResourceBrowser_Load(object sender, EventArgs e)
        {
            RefreshFolders();
            label1.Text = string.Format(label1.Text, string.Join(", ", AllowedResourceTypes.ToArray()));
        }

        private void RefreshFolders()
        {
            treeViewFolders.BeginUpdate();
            try
            {
                treeViewFolders.Nodes.Clear();
                FillSubFolders(treeViewFolders.Nodes, Configuration.Default.ResourcePath);
                foreach (TreeNode node in treeViewFolders.Nodes)
                {
                    node.Expand();
                }
            }
            finally
            {
                treeViewFolders.EndUpdate();
            }
        }

        private void FillSubFolders(TreeNodeCollection treeNodeCollection, string path)
        {
            foreach (var folder in Directory.GetDirectories(path).Where(d => !Path.GetFileName(d).StartsWith("_")).OrderBy(d => d.ToLower()))
            {
                if (!new DirectoryInfo(folder).Attributes.HasFlag(FileAttributes.Hidden))
                {
                    var node = treeNodeCollection.Add(Path.GetFileName(folder));
                    node.ImageIndex = 0;
                    node.Tag = folder;
                    FillSubFolders(node.Nodes, folder);
                }
            }
        }

        private void treeViewFolders_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (treeViewFolders.SelectedNode != null)
            {
                RefreshFiles();
            }
        }

        private void RefreshFiles()
        {
            string path = (string)treeViewFolders.SelectedNode.Tag;
            listViewFiles.BeginUpdate();
            try
            {
                listViewFiles.Items.Clear();
                foreach (string file in Directory.GetFiles(path).OrderBy((f) => GetSortValue(f)))
                {
                    var resourceType = ResourceTypeFactory.Get(file);
                    if (AllowedResourceTypes.Contains(resourceType))
                    {
                        var node = listViewFiles.Items.Add(Path.GetFileName(file));
                        node.Tag = file;
                        node.SubItems.Add(resourceType.ToString());
                    }
                }
            }
            finally
            {
                listViewFiles.EndUpdate();
            }
        }

        private object GetSortValue(string f)
        {
            if (checkBoxDetectNumber.Checked)
            {
                Regex regexNumber = new Regex("\\d+");
                StringBuilder sb = new StringBuilder();
                foreach (Match match in regexNumber.Matches(f))
                {
                    if (match.Success)
                    {
                        sb.Append(int.Parse(match.Value).ToString("0000000"));
                    }
                }
                return sb.ToString();
            }
            else
            {
                return f.ToLower();
            }
        }

        public List<ResourceType> AllowedResourceTypes { get; private set; }

        public IEnumerable<string> SelectedResources
        {
            get
            {
                List<string> resources = new List<string>();
                foreach (ListViewItem node in listViewFiles.SelectedItems)
                {
                    resources.Add(ResourceIO.GetRelative((string)node.Tag));
                }
                return resources;
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            RefreshFiles();
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BusyBox.ShowBusy("Working...");
            listViewFiles.BeginUpdate();
            try
            {
                for (int i = 0; i < listViewFiles.Items.Count; i++)
                {
                    listViewFiles.SelectedIndices.Add(i);
                }
            }
            finally
            {
                listViewFiles.EndUpdate();
                BusyBox.HideBusy();
            }
        }

        private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BusyBox.ShowBusy("Working...");
            listViewFiles.BeginUpdate();
            try
            {
                foreach (ListViewItem item in listViewFiles.Items)
                {
                    item.Selected = !item.Selected;
                }
            }
            finally
            {
                listViewFiles.EndUpdate();
                BusyBox.HideBusy();
            }
        }

        private void listViewFiles_Click(object sender, EventArgs e)
        {
            if (listViewFiles.SelectedItems.Count > 0)
            {
                PreviewSprite = new Bitmap(listViewFiles.SelectedItems[0].Tag as string);
            }
        }

        private void panelPreviewSprite_Paint(object sender, PaintEventArgs e)
        {
            if (PreviewSprite != null)
            {
                int spriteWidth = PreviewSprite.Width;
                int width = Math.Min(panelPreviewSprite.Width, spriteWidth);
                int spriteHeight = PreviewSprite.Height;
                e.Graphics.DrawImage(PreviewSprite, new Rectangle(0,0, width, (int)((float)width / spriteWidth * spriteHeight)));
            }
        }

        private Bitmap _previewSprite;
        private Bitmap PreviewSprite
        {
            get
            {
                return _previewSprite;
            }
            set
            {
                _previewSprite = value;
                panelPreview.Visible = _previewSprite != null;
                panelPreview.Refresh();
            }
        }

        private void splitter2_SplitterMoved(object sender, SplitterEventArgs e)
        {
            panelPreview.Refresh();
        }



    }
}
